package com.example.demo.controller.voj;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.common.IdParam;
import com.example.demo.dto.*;
import com.example.demo.param.voj.SubmissionCreateParam;
import com.example.demo.param.voj.SubmissionDayGroupParam;
import com.example.demo.param.voj.SubmissionLatestQueryParam;
import com.example.demo.param.voj.SubmissionPeriodParam;
import com.example.demo.service.SubmissionService;
import com.example.demo.service.VojSubmissionsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 题库模块 - 提交记录
 */
@Controller
@RequestMapping("/submission")
public class SubmissionController {

    private static final Logger LOGGER = LoggerFactory.getLogger(SubmissionController.class);

    private static final int QUERY_SIZE = 100;

    @Resource
    private SubmissionService submissionService;
    @Resource
    private VojSubmissionsService vojSubmissionsService;

    /**
     * 创建提交
     */
    @RequestMapping(value="/create", method= RequestMethod.POST)
    @ResponseBody
    public ResponseDto<Long> createSubmission(@RequestBody SubmissionCreateParam param) {
        ResponseDto responseDto = new ResponseDto<>().buildSucceed();
        Long result = vojSubmissionsService.createSubmission(param);

        responseDto.setContent(result);
        return responseDto;
    }

    /**
     * 获取用户成功解题数量.
     */
    @RequestMapping(value="/getSolveProblemCount", method= RequestMethod.POST)
    @ResponseBody
    public ResponseDto<SolveProblemCountReturnDto> getSolveProblemCount() {
        ResponseDto responseDto = new ResponseDto<>();
        SolveProblemCountReturnDto data = vojSubmissionsService.getSolveProblemCount();
        responseDto.setContent(data);
        return responseDto;
    }


    /**
     * 获取某个用户对某个试题的提交记录
     * @param idParam
     * @return
     */
    @RequestMapping(value="/getLatestResult", method= RequestMethod.POST)
    @ResponseBody
    public ResponseDto<List<LatestSubmissionResultDto>> getSubmissionResult(@RequestBody IdParam idParam) {
        ResponseDto responseDto = new ResponseDto<>().buildSucceed();
        List<LatestSubmissionResultDto> trainingSubmissionList = vojSubmissionsService.getSubmissionResult(idParam);
        responseDto.setContent(trainingSubmissionList);
        return responseDto;
    }

    /**
     * 获取几天内提交的数量, 并按天数汇总.
     * @return
     */
    @RequestMapping(value="/getNumberOfSubmissionsGroupByDay", method= RequestMethod.POST)
    @ResponseBody
    public ResponseDto<List<SubmissionGroupDayDto>> getNumberOfSubmissionsGroupByDay(@RequestBody SubmissionDayGroupParam param) {

        ResponseDto responseDto = new ResponseDto<>().buildSucceed();
        DateTime today = DateUtil.date();
        DateTime previousDate = DateUtil.offsetDay(DateUtil.date(), param.getPeriod());
        List<SubmissionGroupDayDto> numberOfSubmissionsGroupByDay = vojSubmissionsService.getNumberOfSubmissionsGroupByDay(previousDate, today, false);
        responseDto.setContent(numberOfSubmissionsGroupByDay);
        return responseDto;
    }
    /**
     * 获取几天内提交的数量, 并按天数和语言汇总.
     */
    @RequestMapping(value="/getNumberOfSubmissionsGroupByDayAndLanguage", method= RequestMethod.POST)
    @ResponseBody
    public ResponseDto<List<SubmissionGroupDayLanguageDto>> getNumberOfSubmissionsGroupByDayAndLanguage(@RequestBody SubmissionDayGroupParam param) {
        ResponseDto responseDto = new ResponseDto<>().buildSucceed();
        DateTime today = DateUtil.date();
        DateTime previousDate = DateUtil.offsetDay(DateUtil.date(), param.getPeriod());
        List<SubmissionGroupDayLanguageDto> numberOfSubmissionsGroupByDay = vojSubmissionsService.getNumberOfSubmissionsGroupByDayAndLanguage(previousDate, today, false);
        responseDto.setContent(numberOfSubmissionsGroupByDay);
        return responseDto;
    }

    /**
     * 获取指定时间内提交的数量, 并按月份汇总.
     */
    @RequestMapping(value="/getSubmissionsGroupBySpecifyDurationByMonth", method= RequestMethod.POST)
    @ResponseBody
    public ResponseDto<SubmissionPeriodReturnDto> getNumberOfSubmissionsGroupByMonth(@RequestBody SubmissionPeriodParam param) throws ParseException {

        ResponseDto responseDto = new ResponseDto<>().buildSucceed();
        SubmissionPeriodReturnDto result = vojSubmissionsService.getNumberOfSubmissionsGroupByMonth(param.getStartTime(), param.getEndTime());
        responseDto.setContent(result);
        return responseDto;
    }

    /**
     * 获取最新的评测记录列表.
     * 用于定时获取最新的评测记录.
     */
    @RequestMapping(value="/getLatestSubmissions", method= RequestMethod.POST)
    @ResponseBody
    public ResponseDto<Page<LatestSubmissionResultDto>> getLatestSubmissionsForAll(@RequestBody SubmissionLatestQueryParam param) {
        ResponseDto responseDto = new ResponseDto<>().buildSucceed();
        Page<LatestSubmissionResultDto> result = vojSubmissionsService.getLatestSubmissions(param);
        responseDto.setContent(result);
        return responseDto;
    }


    // TODO 下面接口不知道需不需要


    @RequestMapping(value="/getSubmissionsGroupBySpecifyDurationByDay", method= RequestMethod.POST)
    public @ResponseBody
    ResponseDto getNumberOfSubmissionsGroupByDay(
            @RequestParam(value="uid", required=false, defaultValue="0") long uid,
            @RequestParam(value="startTime") String startTime,
            @RequestParam(value="endTime") String endTime) throws ParseException {

        ResponseDto<Object> responseDto = new ResponseDto<>();
        responseDto.setSuccess(true);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        Date start = simpleDateFormat.parse(startTime);
        Date end = simpleDateFormat.parse(endTime);
        List<Map<String, Object>> acceptSubmissionList = submissionService.getNumberOfSubmissionsGroupByDay(start, end, uid, true);
        List<Map<String, Object>> totalSubmissionList = submissionService.getNumberOfSubmissionsGroupByDay(start, end, uid, false);

        HashMap<String, Map<String, Long>> submissionStatistics = new HashMap<>(2, 1);

        submissionStatistics.put("acceptSubmissionListByDay", sortDateListMapForGroupByDay(acceptSubmissionList));
        submissionStatistics.put("totalSubmissionListByDay", sortDateListMapForGroupByDay(totalSubmissionList));
        responseDto.setContent(submissionStatistics);
        return responseDto;
    }



    @RequestMapping(value="/getExamSubmissionRecord", method= RequestMethod.POST)
    public @ResponseBody
    ResponseDto getExamSubmissionRecord(
            @RequestParam(value="examName", required=false, defaultValue="") String examName,
            @RequestParam(value="page") int page,
            @RequestParam(value="size") int size,
            @RequestParam(value="userName", required=false, defaultValue="") String userName,
            @RequestParam(value="problemName", required=false, defaultValue="") String problemName) {
        ResponseDto<Object> responseDto = new ResponseDto<>();
        responseDto.setContent(submissionService.getExamSubmissionRecord(examName, userName, problemName, page, size));
        return responseDto;
    }

    @RequestMapping(value="/getHomeworkSubmissionRecord", method= RequestMethod.POST)
    public @ResponseBody
    ResponseDto getHomeworkSubmissionRecord(
            @RequestParam(value="className", required=false, defaultValue="") String className,
            @RequestParam(value="page") int page,
            @RequestParam(value="size") int size,
            @RequestParam(value="userName", required=false, defaultValue="") String userName,
            @RequestParam(value="problemName", required=false, defaultValue="") String problemName) {
        ResponseDto<Object> responseDto = new ResponseDto<>();
        responseDto.setContent(submissionService.getHomeworkSubmissionRecord(className, userName, problemName, page, size));
        return responseDto;
    }



    private Map<String, Long> sortDateListMapForGroupByDay(List<Map<String, Object>> submissionList) {
        TreeMap<String, Long> result = new TreeMap<>((Comparator<String>) (o1, o2) -> o1.compareTo(o2));


        for (Map<String, Object> dateMap : submissionList) {
            result.put(dateMap.get("date").toString(), (Long) dateMap.get("submissions"));
        }

        return result;
    }

}
